﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Conversion_Script
{
    public class Matrix  
    {
        string[,] Content;

        int rowcount;
        int columncount;
        public int  RowCount
        {
            get
            {
                return rowcount;
            }
        }
        public int ColumnCount
        {
            get
            {
                return columncount;
            
            }
        }
        public void SetValue(string rowlabel, string columnlabel, string value)
        {
            Content[GetRowNumber(rowlabel), GetColumnNumber(columnlabel)] = value;
        }
        public void SetValue(int r, string columnlabel, string value)
        {
            Content[r, GetColumnNumber(columnlabel)] = value;
        }
        public void AddValue(int r, int c, float value)
        {
                Content[r, c] = (float.Parse(Content[r, c]) + value).ToString();
        }
        public void SetValue(int r, int c, string value)
        {
            Content[r, c] = value;
        }
        public string GetValue(string rowlabel, string header)
        {
            
            //System.Console.WriteLine(rowlabel +"\t"+ Content[GetRowNumber(rowlabel), GetColumnNumber(header)]);
            return Content[GetRowNumber(rowlabel), GetColumnNumber(header)];
        }
        public string GetValue(string rowlabel, int c)
        {
            return Content[GetRowNumber(rowlabel), c];
        }
        public string GetValue(int r, string header)
        {
            return Content[r, GetColumnNumber(header)];
        }

        public string GetValue(int r, int c)
        {
            return Content[r,c];
        }
        int GetRowNumber(string label)
        {
            for (int r = 0; r < RowCount; r++)
            {
                if (GetValue(r, 0).Trim() == label)
                {
                    return r;
                }
            }
            throw new System.Exception("Cannot find rowlabel " + label);
        }
        public int GetColumnNumber(string header)
        {
            for (int c = 0; c < ColumnCount ; c++)
            {
                if (Content[0, c].Trim() == header)
                {
                    return c;
                }
            }
            throw new System.Exception("Cannot find header "+ header);
        }

        public string[] GetRow(int r)
        {
            string[] Row = new string[ColumnCount];
            for (int c = 0; c < ColumnCount; c++)
            {
                Row[c] = Content[r, c];
            }
            return Row;
        }
        public string[] GetColumn(int c)
        {
            string[] column = new string[RowCount];
            for (int r = 0; r < RowCount; r++)
            {
                column[r] = Content[r, c];
            }
            return column;
        }
        public string[] GetColumn(string header)
        {
            return GetColumn(GetColumnNumber(header));
        }
        public string[] GetRow(string rowlabel)
        {
            return GetRow(GetRowNumber(rowlabel));
        }

        void EnsureEqualColumns(string[] FileContent, string FileName)
        {
            foreach(string line in FileContent)
            {
                string _line = line.Trim();
                if (_line.Contains(">>")) _line = _line.Remove(_line.IndexOf(">>"));
                if (_line.Length == 0) continue;
                string hdr = FileContent[0].Trim();
                if (_line.Split('\t').Length != hdr.Split('\t').Length)
                {
                    throw new System.Exception("Unexpected file format " + FileName);
                }
            }
        }

        
        public void Write(string filename)
        {
            string[] Content = new string[RowCount];
            for (int r = 0; r < RowCount; r++)
            {
                for (int c = 0; c < ColumnCount; c++)
                {
                    Content[r] += GetValue(r, c) + "\t";
                }
            }
            System.IO.File.WriteAllLines(filename, Content);
        }

        
        string[] RemoveEmptyLines(string[] FileContent)
        {
            List<string> FileContentOut = new List<string>();
            for (int r = 0; r < FileContent.Length; r++)
            {
                string line = FileContent[r].Trim();

                if (line.Length > 0)
                {
                    FileContentOut.Add(line);
                }
            }
            return FileContentOut.ToArray();
        }
        public Matrix(int RowCount, string[] Headers)
        {
            columncount = Headers.Length;
            rowcount = RowCount;

            Content = new string[RowCount , Headers.Length];

            for (int h = 0; h < Headers.Length; h++)
            {
                SetValue(0, h, Headers[h]);
            }

        }
        public Matrix(string FileName)
        {
            string[] FileContent = System.IO.File.ReadAllLines(FileName);

            EnsureEqualColumns(FileContent, FileName);

            FileContent = RemoveEmptyLines(FileContent);

            columncount = FileContent[0].Split('\t').Length;
            rowcount = FileContent.Length;

            Content = new string[rowcount , columncount];

            for (int r = 0; r < FileContent.Length;r++ )
            {
                if (FileContent[r].Trim().Length == 0) continue;
                string[] terms = FileContent[r].Trim().Split('\t');
                
                for (int c = 0; c < terms.Length; c++)
                {

                    Content[r, c] =  terms[c];
                }
            }
            
        }
    }
}
